package pers.xiaojun.boot.module.system.convert;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Sets;
import lombok.extern.log4j.Log4j2;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import pers.xiaojun.boot.common.util.CollectionUtils;
import pers.xiaojun.boot.module.system.constants.MenuConstants;
import pers.xiaojun.boot.module.system.controller.auth.vo.AuthLoginRespVO;
import pers.xiaojun.boot.module.system.controller.auth.vo.AuthPermissionInfoRespVO;
import pers.xiaojun.boot.module.system.dao.entity.permission.MenuDO;
import pers.xiaojun.boot.module.system.dao.entity.permission.RoleDO;
import pers.xiaojun.boot.module.system.dao.entity.user.AdminUserDO;
import pers.xiaojun.boot.module.system.enums.permission.MenuTypeEnum;
import pers.xiaojun.boot.module.system.service.oauth2.dto.OAuth2TokenDTO;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述
 *
 * @author xiaojun
 * @since 2025-10-05
 */
@Mapper
public interface AuthConvert {

    AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class);

    /**
     * oAuth2TokenDTO -> AuthLoginRespVO
     */
    AuthLoginRespVO toAuthLoginRespVO(OAuth2TokenDTO oAuth2TokenDTO);

    /**
     * 转换为 toAuthPermissionInfoRespVO
     *
     * @param user  用户信息
     * @param roles 角色列表信息
     * @param menus 菜单列表信息
     * @return 用户权限信息
     */
    default AuthPermissionInfoRespVO toAuthPermissionInfoRespVO(AdminUserDO user, List<RoleDO> roles, List<MenuDO> menus) {
        return new AuthPermissionInfoRespVO()
                .setUser(BeanUtil.toBean(user, AuthPermissionInfoRespVO.UserVO.class))
                .setRoles(Sets.newHashSet(CollectionUtils.convertList(roles, RoleDO::getCode)))
                .setPermissions(Sets.newHashSet(CollectionUtils.convertList(menus, MenuDO::getPermission)))
                .setMenus(toMenuTree(menus));
    }

    /**
     * 转菜单树
     *
     * @param menus 菜单列表信息
     * @return 菜单树
     */
    default List<AuthPermissionInfoRespVO.MenuVO> toMenuTree(List<MenuDO> menus) {
        if (CollUtil.isEmpty(menus)) {
            return new ArrayList<>();
        }
        // 删除按钮
        menus.removeIf(menu -> MenuTypeEnum.BUTTON.getType().equals(menu.getType()));
        // 排序
        menus.sort(Comparator.comparing(MenuDO::getSort));
        // 有序Map集合
        LinkedHashMap<Long, AuthPermissionInfoRespVO.MenuVO> treeNodeMap = new LinkedHashMap<>();
        // 转Map
        menus.forEach(menu -> treeNodeMap.put(menu.getId(), BeanUtil.toBean(menu, AuthPermissionInfoRespVO.MenuVO.class)));
        // 遍历所有子节点
        treeNodeMap.values().stream().filter(menu -> !menu.getParentId().equals(MenuConstants.ROOT_MENU_ID)).forEach(menu -> {
            // 父节点
            AuthPermissionInfoRespVO.MenuVO parentNode = treeNodeMap.get(menu.getParentId());
            if (parentNode.getChildren() == null) {
                parentNode.setChildren(new ArrayList<>());
            }
            parentNode.getChildren().add(menu);
        });
        // 保留根节点，并返回
        return treeNodeMap.values().stream()
                .filter(menu -> menu.getParentId().equals(MenuConstants.ROOT_MENU_ID))
                .toList();
    }


}
